package kgame5.k3d.pars {
import kgame5.enginex.WorldRender;
import kgame5.enginex.enum.Layer3DEnum;
import kgame5.k3d.core.obj3d.hardvo.HardVO;
import kgame5.k3d.core.obj3d.node3d.Group3D;
import kgame5.k3d.core.obj3d.node3d.Node3D;
import kgame5.kutil.T;

import flash.utils.Dictionary;

/**
 * @author kk
 * 粒子系统的引擎
 * 粒子系统功能有待增强。多参考成熟的粒子系统吧
 * !!注意，用aPar存储粒子，因为涉及的删除操作较多，所以会比较浪费资源，这里使用dict来存储
 */
public class ParticlesEngine {
	
	//_________________Property_______________________
	//存储的是各个md,就是一个个的粒子
	//private  var aPars:Array=null;
	
	private var dict_par:Dictionary=null;
	
	//存储的是每个粒子特效的容器，md_g,当md_g的childCount为0,需要把md_g清除
	//注意，之所以每组存储成为粒子，也是出于性能的考虑，减少全局排序
	private  var dict_group:Dictionary=null;
	
	//粒子组被添加到的位置,这个是说粒子被添加到指定图层
	//tip层，core层,地面层等
	private var root:WorldRender;
	
	//_______________Method____________________
	
	private static var instance:ParticlesEngine;
	public static function getInstance():ParticlesEngine{
		if(instance==null){
			instance=new ParticlesEngine();
		}
		return instance;
	}
	
	public function ParticlesEngine(){
	}
	
	public function setRoot(_root:WorldRender):void{
		this.root=_root;
	}

	//	//root表示的是将group要添加到哪里
//	public  function init(root:Group3D):void{
//		aPars=new Array();
//		dict_group=new Dictionary(true);
//	}

	public function clear():void{
		T.p("ParsM.Clear()清空粒子效果");
		//aPars=null;
		dict_par=null;
		
		//清除组就可以了
		for each(var md_g:Node3D in dict_group){
			md_g.dispose();//不需要通知外部的，这个就能直接消除自己的
		}
		dict_group=null;
	}
	
	private function addPar(md_par:Node3D):void{
		if(dict_par==null){
			dict_par=new Dictionary();
		}
		dict_par[md_par.bornID]=md_par;
		//aPars.push(md_par);
	}
	
	//做好一个粒子效果都放到一个md_g里去，然后向parsM添加
	public function addGroup(md_g:Group3D):void{
		
		//真正添加到舞台,添加到舞台的指定层
		if(root!=null){//在enginex中使用这个
			if(md_g.layerID!=Layer3DEnum.LAYER_NULL){//LAYER_NULL表示不需要添加到舞台
				root.addChild(md_g, md_g.layerID);
			}
		}
		
		if(dict_group==null){
			dict_group=new Dictionary();
		}
		dict_group[md_g.bornID]=md_g;
		
//		for(var i:int=0;i<md_g.getChildCount();i++){
//			var md_par:Model3D=md_g.getChildAt(i);
//			addPar(md_par);
//		}
		
		for each(var md_par:Node3D in md_g.getChildren()){
			addPar(md_par);
		}
	}
	
	private function removePar(md_par:Node3D):void{
		//T.p("removePar");
		//aPars.splice(idx,1);
		delete dict_par[md_par.bornID];
		
		md_par.dispose();//注意这个要先放在前面啊
		
		var md_g:Group3D=md_par.getParent();
		if(md_g.getChildCount()==0){
			removeGroup(md_g);
		}
	}
	//当一个组里的粒子都消亡的时候
	private function removeGroup(md_g:Group3D):void{
		//T.p("removeGroup");
		delete dict_group[md_g.bornID];
		
		md_g.dispose();
	}
	
	//运行粒子
	public function update():void{
		if(dict_par==null){
			return;
		}
//		var len:int=aPars.length;
//		if(len==0){
//			return;
//		}
		
		//for(var i:int=len-1;i>=0;i--){//注意这个是倒着放的顺序,因为会有删除
			
		//var md:Node3D=aPars[i] as Node3D;
		for each(var md:Node3D in dict_par){
			var hv:HardVO=md.ti.hardVO;
			
			//位置
			hv.v3d_v.add(hv.v3d_a);//速度
			hv.v3d_p.add(hv.v3d_v);//位置
			//旋转
			hv.v3d_r.add(hv.v3d_rv);//getDO().rotation+=md.getProp(1);
			//缩放
			hv.v3d_s.add(hv.v3d_sv);
			//alpha
			md.getDO().alpha += md.alphaSpeed;
			
			var isDead:Boolean=false;
			
			//生命
			if(md.life!=-1){//这个是按时间计算生命的
				md.life--;
				
				if(md.life<=0 
					||hv.v3d_s.x<=0
					||md.getDO().alpha<=0 
					){
					isDead=true;
					//T.p("删除一个:"+aModel.length+" "+world.size());
				}
			}else{//life==-1的条件是落地就消失
				//trace("life=-1",md.v3d_p.y,md.H/2);
				if(hv.v3d_p.y+hv.aabb.H/2<=0){
					isDead=true;
				}
			}
			
			//如果死了就真正删除
			if(isDead){
				removePar(md);
			}
		}
	}
	
}//end of class
}
